import {all, put, take, takeEvery, call, cps, fork, cancel} from '../../redux-saga/effects';
import {loginFlow} from './login';
import {recorder} from './record';
import * as types from '../action-types';

function *autoAddWorker(){
  while (true){
    yield delay(1000);
    yield put({type: types.INCREMENT});
  }
}

function *autoAddWatcher(){
  const task = yield fork(autoAddWorker); //会开启一个新的子进程去执行, 返回一个task任务对象 可以用于取消
  yield take(types.STOP);
  yield cancel(task);
}

function *add1(){
  for (let i = 0; i < 2; i++) {
    yield take(types.ASYNC_INCREMENT);
    yield put({type: types.INCREMENT});
  }
  return 'add1';
}

function *add2(){
  for (let i = 0; i < 3; i++) {
    yield take(types.ASYNC_INCREMENT);
    yield put({type: types.INCREMENT});
  }

  return 'add2';
}

const readFile = function (filename: any, callback: any) {
  setTimeout(() => {
    callback(null/*一般第一个参数是错误*/, filename + '的内容');
  }, 1000)
};

const delay = (ms: number) => new Promise((resolve,reject)=>{
  setTimeout(resolve, ms);
})

const delay2 = (ms: number, cb: Function) => {
  setTimeout(() => cb(null, 'delay结果'), ms);
}

const ajax = (url: string) => {
  return fetch(url).then(res => res.json())
};

function *worker_add(){
  yield put({type: types.INCREMENT});

  //yield take('abc');
  console.log('add next'); //如果这行之前不是同步的 会晚于 'rootSaga next' 打印, 比如像上面一样take一下
}

function *watcher_add(){
  yield takeEvery(types.ASYNC_INCREMENT, worker_add);
}

export default function* rootSaga(){
  console.log('启动rootSaga');

  /** case1: take 和 put*/
  /*for (let i = 0; i < 3; ++i) {
    yield take(types.ASYNC_INCREMENT); //等待有人向仓库发一个 ASYNC_INCREMENT, 等到了就继续执行, 等不到就一直卡在这里 //take 只会等一次
    yield put({type: types.INCREMENT}); //向仓库派发一个动作, 让仓库调用store.dispatch({type: types.INCREMENT})
    //take put 执行后都会返回一个普通的指令对象, 用来指挥saga中间件做一些事情, 监听啊 派发动作啊
  }*/
  //↑ 可以点三次【异步+1】btn, 三次以后就没用了


  /** case2: yield的是另外一个生成器的迭代器*/
  /*for (let i = 0; i < 3; i++) {
    yield take(types.ASYNC_INCREMENT);
    yield add()/!*←产出一个iterator*!/;
    console.log('rootSaga next');
  }*/


  /** case3: takeEvery、fork*/
  /*/!*while (true){
    yield take(types.ASYNC_INCREMENT);
    yield add();
    console.log('rootSaga next');
  }*!/
  //↕等价
  //yield takeEvery(types.ASYNC_INCREMENT, worker_add);
  //↕等价
  yield watcher_add();
  console.log('====================================');
  console.log('rootSaga next');
  console.log('====================================');*/


  /** case4: promise*/
  /*console.log('before delay');
  yield delay(2000);
  //yield ajax('/xxx');
  console.log('after delay');*/

  /** case5: call*/
  /*console.log('before delay');
  yield call(delay, 2000);
  console.log('after delay');*/

  /** case6: cps*/
  //如果你的异步任务返回的不是promise 而是以回调的形式
  //那么可以使用此方法
  /*console.log('before delay');
  yield cps(delay2,2000)
  console.log('after delay');*/


  /** case7: all*/
  //watcher 你也可以认为是一个flow,
  // 一般一个watcher会拆分出去,
  // 然后在root里统一引用所有watcher,
  // yield all
  /*const result = yield all([add1(),add2()])
  console.log('done', result); //result是个数组, 第一个就是第一个返回的结果, 第二个就是第二个返回的结果*/


  /** case8: cancel*/
  yield autoAddWatcher();


  //yield all([loginFlow(),recorder()])
}
